<?php
/**
* productcategory.php
*
* Create on 2017-2-19
* Create by TT
*/
namespace haibao\cms\data\newproduct;

use \haibao\frame\data\query\Condition;
use \haibao\cms\model\filter\newproduct\ProductCategoryDefine as ProductCategoryFilter;
use \haibao\cms\model\data\newproduct\ProductCategoryDefine as ProductCategoryModel;

class ProductCategory extends \haibao\cms\data\BaseMysql{
	
	private static $cacheCategoryListName = 'CategoryList';
	private static $cacheCategoryArr = 'CategoryArr';
	private static $cacheCategoryChildrenArr = 'CategoryChildrenArr';
	
	public function __construct(){
		parent::__construct('\haibao\cms\model\data\newproduct\ProductCategoryDefine');
	}
	
	public function getCategoryById($categoryId){
		$productCategoryFilter = new ProductCategoryFilter();
		$productCategoryFilter->select(array(
				ProductCategoryFilter::CONDITION_FIELD_NAME_ID,
				ProductCategoryFilter::CONDITION_FIELD_NAME_CATEGORY_NAME
		));
		$productCategoryFilter->where(ProductCategoryFilter::CONDITION_FIELD_NAME_STATUS, Condition::CONDITION_EQUAL, ProductCategoryModel::STATUS_ENABLE);
		
		$productCategoryMapFilter = new \haibao\cms\model\filter\newproduct\ProductCategoryMap();
		$productCategoryMapFilter->select(array(
				$productCategoryMapFilter::CONDITION_FIELD_NAME_PARENT_ID
		));
		$productCategoryMapFilter->where($productCategoryMapFilter::CONDITION_FIELD_NAME_CATEGORY_ID, Condition::CONDITION_EQUAL, $categoryId);
		$productCategoryFilter->leftJoin($productCategoryMapFilter,null,ProductCategoryFilter::CONDITION_FIELD_NAME_ID,$productCategoryMapFilter::CONDITION_FIELD_NAME_CATEGORY_ID,ProductCategoryFilter::CONDITION_FIELD_NAME_PARENT_IDS);
		
		return $this->getOne($productCategoryFilter);
	}
	
	public function getChildListByCategoryId($categoryId){
		$productCategoryMapFilter = new \haibao\cms\model\filter\newproduct\ProductCategoryMap();
		$productCategoryMapFilter->select(array(
				$productCategoryMapFilter::CONDITION_FIELD_NAME_CATEGORY_ID
		));
		$productCategoryMapFilter->where($productCategoryMapFilter::CONDITION_FIELD_NAME_PARENT_ID, Condition::CONDITION_EQUAL, $categoryId);
		
		return $this->getAll($productCategoryMapFilter);
	}
	
	public function deleteCategory($categoryId){
		parent::updateById($categoryId, array('Status'=>\haibao\cms\model\data\newproduct\ProductCategoryDefine::STATUS_DISABLE));
		$sql = "Delete from ProductCategoryMap_New where CategoryId=%s";
		$this->query($sql,array($categoryId));
		$this->clearCache();
	}
	
	public function addCategory($model){
		self::beginTranscation();
		try{
			$this->add($model);
			if($model->ParentIds){
				$categoryMapModels = array();
				foreach($model->ParentIds as $parentId){
					$categoryMapModel = new \haibao\cms\model\data\newproduct\ProductCategoryMap();
					$categoryMapModel->CategoryId = $model->Id;
					$categoryMapModel->ParentId = $parentId;
					$categoryMapModels[] = $categoryMapModel;
				}
		
				$this->addAll($categoryMapModels);
			}
				
			$this->clearCache();
		
		}catch (\Exception $e){
			$this->rollback();
			throw $e;
		}
		$this->endTranscation();
	}
	
	public function saveCategory($model){
		$arrSet = array();
		$arrSet[ProductCategoryFilter::CONDITION_FIELD_NAME_CATEGORY_NAME] = $model->CategoryName;
		self::beginTranscation();
		try{
			$this->updateById($model->Id, $arrSet);
			$sql = "Delete from ProductCategoryMap_New where CategoryId=%s";
			$this->query($sql,array($model->Id));
			if($model->ParentIds){
				$categoryMapModels = array();
				foreach($model->ParentIds as $parentId){
					$categoryMapModel = new \haibao\cms\model\data\newproduct\ProductCategoryMap();
					$categoryMapModel->CategoryId = $model->Id;
					$categoryMapModel->ParentId = $parentId;
					$categoryMapModels[] = $categoryMapModel;
				}
				
				$this->addAll($categoryMapModels);
			}
			
			$this->clearCache();
		
		}catch (\Exception $e){
			$this->rollback();
			throw $e;
		}
		$this->endTranscation();
	}
	
	/**
	 * 获取分类结构
	 * @return array
	 */
	public function getCategoryList(){
		$categoryListCache = null;//$this->getCache(self::$cacheCategoryListName);
		return $categoryListCache ? $categoryListCache : $this->setCategoryList();
	}
	
	public function getCategoryArr(){
		$categoryArr = null;//$this->getCache(self::$cacheCategoryArr);
		return $categoryArr ? $categoryArr : $this->setCategoryArr();
	}

	public function getCategoryChildrenArr(){
		$categoryChildrenList = $this->getCache(self::$cacheCategoryChildrenArr);
		return $categoryChildrenList ? $categoryChildrenList : $this->setCategoryChildrenArr();
	}
	
	public function getCategoryChildrenIds($categoryId){
		$categoryList = $this->getCategoryList();
		$categoryChildrenIds = array();
		if($categoryList){
			$categoryChildrenIds = $this->getChildrenCategoryIds($categoryId,$categoryList);
		}
		return $categoryChildrenIds;
	}
	
	
	private function setCategoryChildrenArr(){
		$categoryList = $this->getCategoryList();
		$categoryChildrenList = array();
		if($categoryList){
			$categoryChildrenList = $this->getChildrenCategory($categoryList);
		}
		if($categoryChildrenList){
			$this->setCache(self::$cacheCategoryChildrenArr, $categoryChildrenList);
		}
		return $categoryChildrenList;
	}
	
	private function getChildrenCategory($category,$parentId = array(),$categoryParentName = ''){
		$categoryArr = array();
		foreach($category as $key =>$category){
			$name = $category['CategoryName'];
			$parentIds = array($category['Id']);
			if($categoryParentName){
				$name = $categoryParentName.'->'.$name;
			}
			if($parentId){
				$parentIds = array_merge($parentId,$parentIds);
			}
			if(!empty($category['Children'])){
				$categoryArr = array_merge($categoryArr,$this->getChildCategory($category['Children'],$parentIds,$name));
			} else {
				return array('Id'=>$category['Id'],'Name'=>$name,'ParentIds'=>$parentIds);
			}
		}
		return $categoryArr;
	}
	
	private function getChildrenCategoryIds($categoryId,$category,$isDecide = true,$childrenId = array()){
		$categoryArr = array();
		foreach($category as $key =>$category){
			if($isDecide){
				if($category['Id'] == $categoryId){
					$isDecide = false;
					if(!empty($category['Children'])){
						$categoryArr = array_merge($categoryArr,$this->getChildrenCategoryIds($category['Id'],$category['Children'],$isDecide));
					}
					break;
				} else {
					if(!empty($category['Children'])){
						$categoryArr = array_merge($categoryArr,$this->getChildrenCategoryIds($categoryId,$category['Children'],$isDecide));
					}
				}
			} else {
				$childrenIds = array($category['Id']);
				if($childrenIds){
					$childrenIds = array_merge($childrenId,$childrenIds);
				}
				if(!empty($category['Children'])){
					$categoryArr = array_merge($categoryArr,$this->getChildrenCategoryIds($category['Id'],$category['Children'],$isDecide,$childrenIds));
				} else {
					$categoryArr = array_merge($categoryArr,$childrenIds);
				}
			}
		}
		return $categoryArr;
	}
	
	private function setCategoryArr(){
		$categoryList = $this->getCategoryList();
		$categoryArr = array();
		if($categoryList){
			$categoryArr = $this->getChildCategory($categoryList);
		}
		
		if($categoryArr){
			$this->setCache(self::$cacheCategoryArr, $categoryArr);
		}
		
		return $categoryArr;
	}
	
	private function getChildCategory($category,$parentId = array(),$categoryParentName = ''){
		$categoryArr = array();
		foreach($category as $key =>$category){
			$name = $category['CategoryName'];
			$parentIds = array($category['Id']);
			if($categoryParentName){
				$name = $categoryParentName.'->'.$name;
			}
			if($parentId){
				$parentIds = array_merge($parentId,$parentIds);
			}
			$categoryArr[] = array('Id'=>$category['Id'],'Name'=>$name,'ParentIds'=>$parentIds);
			if(!empty($category['Children'])){
				$categoryArr = array_merge($categoryArr,$this->getChildCategory($category['Children'],$parentIds,$name));
			}
		}
		return $categoryArr;
	}
	
	private function setCategoryList(){
		$categoryModels = $this->getCategoryChildrenModels();
		$categorysArr = array();
		if($categoryModels){
			foreach($categoryModels as  $key=>$categoryModel){
				$childrenList = $this->getCategoryChildren($categoryModel->Id);
				$categorysArr[] = array('Id'=>$categoryModel->Id,'CategoryName'=>$categoryModel->CategoryName,'ParentIds'=>array(),'Children'=>$childrenList);
			}
		}
		
		if($categorysArr){
			$this->setCache(self::$cacheCategoryListName, $categorysArr);
		}
		
		return $categorysArr;
	}
	
	private function getCategoryChildren($categoryId,$parentId = array(),&$childrenList = array()){
		$childrenModels = $this->getCategoryChildrenModels($categoryId);
		if($childrenModels){
			foreach($childrenModels as $k=>$childrenModel){
				$parentIds = array($categoryId);
				if($parentId){
					$parentIds = array_merge($parentId,$parentIds);
				}
				$childrenList[] = array('Id'=>$childrenModel->Id,'CategoryName'=>$childrenModel->CategoryName,'ParentIds'=>$parentIds,'Children'=>$this->getCategoryChildren($childrenModel->Id,$parentIds));
			}
		}
		return $childrenList;
	}
	
	private function getCategoryChildrenModels($categoryId = 0){
		$productCategoryFilter = new ProductCategoryFilter();
		$productCategoryFilter->select(array(
				ProductCategoryFilter::CONDITION_FIELD_NAME_ID,
				ProductCategoryFilter::CONDITION_FIELD_NAME_CATEGORY_NAME
		));
		$productCategoryFilter->where(ProductCategoryFilter::CONDITION_FIELD_NAME_STATUS, Condition::CONDITION_EQUAL, ProductCategoryModel::STATUS_ENABLE);
		
		$productCategoryMapFilter = new \haibao\cms\model\filter\newproduct\ProductCategoryMap();
		$productCategoryMapFilter->select(array(
				$productCategoryMapFilter::CONDITION_FIELD_NAME_CATEGORY_ID
		));
		$productCategoryMapFilter->where($productCategoryMapFilter::CONDITION_FIELD_NAME_PARENT_ID, Condition::CONDITION_EQUAL, $categoryId);
		$productCategoryFilter->leftJoin($productCategoryMapFilter,null,ProductCategoryFilter::CONDITION_FIELD_NAME_ID,$productCategoryMapFilter::CONDITION_FIELD_NAME_CATEGORY_ID);
		
		return $this->getAll($productCategoryFilter);
	}
	
	private function clearCache(){
		$this->unsetCache(self::$cacheCategoryListName);
		$this->unsetCache(self::$cacheCategoryArr);
		$this->unsetCache(self::$cacheCategoryChildrenArr);
	}
	
}